home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / OK, What was that again? / Extension / Backup / OK.c next >
C/C++ Source or Header  |  1993-06-17  |  11KB  |  429 lines

  1. #include <Dialogs.h>
  2. #include <GestaltEqu.h>
  3. #ifndef        __TYPES__
  4. #include    <Types.h>
  5. #endif
  6.  
  7. #ifndef        __MEMORY__
  8. #include    <Memory.h>
  9. #endif
  10.  
  11. #ifndef        __ERRORS__
  12. #include    <Errors.h>
  13. #endif
  14.  
  15. #ifndef        __TRAPS__
  16. #include    <Traps.h>
  17. #endif
  18.  
  19. #ifndef        __OSUTILS__
  20. #include    <OSUtils.h>
  21. #endif
  22.  
  23. #ifndef        __TOOLUTILS__
  24. #include    <ToolUtils.h>
  25. #endif
  26.  
  27. #include <Resources.h>
  28. #include <StdDef.h>
  29. #include "OSUtilsSup.h"
  30. #include "Icons.h"
  31.     
  32. pascal void ShowINIT(short iconID, short moveX);
  33. pascal void MessageModalDialog(ModalFilterProcPtr filterProc,short *itemHit);
  34. pascal OSErr MessageGestalt(OSType selector, long *response);
  35. pascal Boolean MessageFilterProc(DialogPtr theDialog, EventRecord* theEvent, short* itemHit);
  36. void foo(void);
  37. void Globals(void);
  38. pascal OSErr DetachIcon(ResType, Handle* theIcon, void*);
  39.  
  40. typedef pascal void (*TModalDialog)(ModalFilterProcPtr, short*);
  41.  
  42. typedef struct SLocals {
  43.     struct SLocals*        oldLocals;
  44.     long                ticks;
  45.     ModalFilterProcPtr    filterProc;
  46.     short                stage;
  47.     Boolean                timedOut;
  48.     Rect                mouseSlop;
  49.     GrafPort            bwPort;
  50.     GrafPort            colorPort;
  51.     Boolean                isBWPort;
  52. };
  53. typedef struct SLocals SLocals;
  54.  
  55. struct SGlobals {
  56.     TModalDialog    modalDialogProc;
  57.     SLocals*        locals;
  58.     
  59.     Handle            iconSuites[6];
  60. };
  61. typedef struct SGlobals SGlobals;
  62.  
  63. void main(void)
  64. {
  65.     SGlobals*    globals        = (SGlobals*)Globals;
  66.     Handle*        iconSuite    = &globals->iconSuites;
  67.     short        i;
  68.     OSErr        error;
  69.     THz            zone;
  70.     
  71.     QHdrPtr q = (QHdrPtr)foo;
  72.     
  73.     q->qFlags = 0;
  74.     q->qHead = 0;
  75.     q->qTail = 0;
  76.     
  77.     NewGestalt('Msg!',(ProcPtr)MessageGestalt);
  78.     
  79.     (void)PatchTrap((ProcPtr*)&globals->modalDialogProc, _ModalDialog, (ProcPtr)MessageModalDialog, 0);
  80.     DetachResource(RecoverHandle((Ptr)main));
  81.     
  82.     zone = GetZone();
  83.     SetZone(SystemZone());
  84.     for (i = 128; i <= 133; ++i) {
  85.         error = GetIconSuite(iconSuite, i, svAllLargeData);
  86.         error = ForEachIconDo(*iconSuite, svAllLargeData, (ProcPtr)DetachIcon, nil);
  87.         ++iconSuite;
  88.     }
  89.     SetZone(zone);
  90.     
  91.     ShowINIT(127,-1);
  92.  
  93. }
  94.  
  95. pascal OSErr DetachIcon(ResType, Handle* theIcon, void*)
  96. {
  97.     if (*theIcon) DetachResource(*theIcon);
  98.     return noErr;
  99. }
  100.  
  101. void Globals(void)
  102. {
  103.     Debugger();
  104.     Debugger();
  105.     Debugger();
  106.     Debugger();
  107.     Debugger();
  108.     Debugger();
  109.     Debugger();
  110.     Debugger();
  111.     Debugger();
  112.     Debugger();
  113.     Debugger();
  114.     Debugger();
  115.     Debugger();
  116.     Debugger();
  117.     Debugger();
  118.     Debugger();
  119.     Debugger();
  120.     Debugger();
  121.     Debugger();
  122.     Debugger();
  123. }
  124.  
  125. void foo(void)
  126. {
  127.     Debugger();
  128.     Debugger();
  129.     Debugger();
  130.     Debugger();
  131.     Debugger();
  132.     Debugger();
  133.     Debugger();
  134.     Debugger();
  135. }
  136.  
  137. pascal OSErr MessageGestalt(OSType, long *response)
  138. {
  139.     *response = (long)foo;
  140.     return noErr;
  141. }
  142.  
  143. typedef struct {
  144.     struct QElem *qLink;            /* QElement header */
  145.     short qType;
  146.     
  147.     PicHandle        picture;
  148.     unsigned long    dateTime;
  149.     Rect            windowRect;
  150. } Q;
  151.  
  152. enum {
  153.     fingerFromLeft    = 7,
  154.     fingerFromTop    = 10,
  155.     fingerSize        = 32,
  156.  
  157.     lastStage        = 5,                        /* Dismiss Dialog when this stage is met */
  158.     secondsPerStage    = 1,                        /* Time for each stage */
  159.     startTime        = 60 * 5,                    /* Start to fade after n seconds */
  160.     delayTime        = 60 * secondsPerStage,        /* Delta between stages in n seconds */
  161.     slopAmount        = 4                            /* Reset when mouse moves by this */
  162. };
  163.  
  164. pascal void MessageModalDialog(ModalFilterProcPtr filterProc,short *itemHit)
  165. {
  166.     SGlobals*    globals = (SGlobals*)Globals;
  167.     PicHandle     picture;
  168.     GrafPtr        theDialog;
  169.     THz            zone;
  170.     Q*            q;
  171.     GrafPtr        oldPort;
  172.     QHdrPtr        qHeader;
  173.     short        itemType;
  174.     Handle        handle;
  175.     Rect        box, iconBox;
  176.     Str255        title;
  177.     SLocals        locals;
  178.     Point        mouse;
  179.     
  180.     GetMouse(&mouse);
  181.     theDialog = FrontWindow();
  182.     
  183.     GetDItem(theDialog, ok, &itemType, &handle, &box);
  184.     
  185.     if (itemType != 4) goto bannana;
  186.     GetCTitle((ControlHandle)handle, title);
  187.     if (title[0] != 2) goto bannana;
  188.     if (title[1] != 'O') goto bannana;
  189.     if (title[2] != 'K') goto bannana;
  190.         
  191.     if ((theDialog->portBits.rowBytes & 0xC000) != 0xC000) {
  192.         locals.isBWPort = true;
  193.         
  194.         BlockMove(theDialog, &locals.bwPort, sizeof(GrafPort)); /* Make a copy of the Port */
  195.         
  196.         GetPort(&oldPort);
  197.         OpenCPort((CGrafPtr)&locals.colorPort);                    /* Init a color Port */
  198.         
  199.         /* Set up the color port to match the bw port */
  200.         PortSize(locals.bwPort.portRect.right - locals.bwPort.portRect.left,
  201.             locals.bwPort.portRect.bottom - locals.bwPort.portRect.top);
  202.         MovePortTo(- locals.bwPort.portBits.bounds.left, - locals.bwPort.portBits.bounds.top);
  203.         CopyRgn(locals.bwPort.visRgn, locals.colorPort.visRgn);
  204.         CopyRgn(locals.bwPort.clipRgn, locals.colorPort.clipRgn);
  205.         BlockMove(&locals.bwPort.pnLoc, &locals.colorPort.pnLoc, offsetof(GrafPort, pnPat) - offsetof(GrafPort, pnLoc));
  206.         BlockMove(&locals.bwPort.pnVis, &locals.colorPort.pnVis, sizeof(GrafPort) - offsetof(GrafPort, pnVis));
  207.         SetPort(oldPort);
  208.     } else {
  209.         locals.isBWPort = false;
  210.     }
  211.         
  212.     locals.filterProc    = filterProc;
  213.     locals.ticks        = TickCount();
  214.     locals.timedOut        = false;
  215.     locals.stage        = 0;
  216.     locals.oldLocals    = globals->locals;
  217.     SetRect(&locals.mouseSlop, mouse.h, mouse.v,
  218.         mouse.h, mouse.v);
  219.     InsetRect(&locals.mouseSlop, -slopAmount, -slopAmount);
  220.     
  221.     globals->locals = &locals;
  222.  
  223. #define CallTheOldTrap    (globals->modalDialogProc)
  224.     
  225.     CallTheOldTrap(MessageFilterProc, itemHit);
  226.     
  227.     globals->locals = locals.oldLocals;
  228.     
  229.     if (locals.timedOut) {
  230.             
  231.         GetPort(&oldPort);
  232.         SetPort(theDialog);
  233.         
  234.         zone = GetZone();
  235.         SetZone(SystemZone());
  236.         picture = OpenPicture(&theDialog->portRect);
  237.         SetZone(zone);
  238.         
  239.         InvalRect(&theDialog->portRect);
  240.         ClipRect(&theDialog->portRect);
  241.     
  242.         /*    If there is a filter proc then send it an update event to force any
  243.             additional drawing. */
  244.         if (filterProc) {
  245.             EventRecord theEvent = { updateEvt, (long)theDialog, TickCount(), { 0, 0 }, 0 };
  246.         
  247.             (void)filterProc(theDialog, &theEvent, itemHit);
  248.         }
  249.         
  250.         if (!EmptyRgn(((WindowPeek)theDialog)->updateRgn)) {
  251.             BeginUpdate(theDialog);
  252.             DrawDialog(theDialog);
  253.             EndUpdate(theDialog);
  254.         }
  255.         
  256.         iconBox.left = ((box.left + box.right) >> 1) - fingerFromLeft;
  257.         iconBox.right = iconBox.left + fingerSize;
  258.         iconBox.top = ((box.top + box.bottom) >> 1) - fingerFromTop;
  259.         iconBox.bottom = iconBox.top + fingerSize;
  260.         ClipRect(&theDialog->portRect);
  261.         PlotIconSuite(&iconBox, atNone, ttNone, globals->iconSuites[lastStage]);
  262.         
  263.         ClosePicture();
  264.         
  265.         
  266.         HiliteControl((ControlHandle)handle, 0);
  267.     
  268.         q = (Q*)NewPtrSys(sizeof(Q));
  269.         q->picture = picture;
  270.         GetDateTime(&q->dateTime);
  271.         q->windowRect = theDialog->portRect;
  272.         LocalToGlobal((Point*)&q->windowRect.top);
  273.         LocalToGlobal((Point*)&q->windowRect.bottom);
  274.         
  275.         if (Gestalt('Msg!', (long*)&qHeader) == noErr) Enqueue((QElemPtr)q, qHeader);
  276.         else {
  277.             DisposePtr((Ptr)q);
  278.             KillPicture(picture);
  279.         }
  280.         
  281.         SetPort(oldPort);
  282.         
  283.         *itemHit = ok;
  284.     }
  285.     if (locals.isBWPort) {
  286.         CloseCPort((CGrafPtr)&locals.colorPort);
  287.     }
  288.     return;
  289. bannana:
  290.     CallTheOldTrap(filterProc, itemHit);
  291. }
  292.  
  293. pascal Boolean MessageFilterProc(DialogPtr theDialog, EventRecord* theEvent, short* itemHit)
  294. {
  295.     SGlobals*    globals    = (SGlobals*)Globals;
  296.     SLocals*    locals    = globals->locals;
  297.     short        itemType;
  298.     Handle        handle;
  299.     Rect        box, iconBox;
  300.     GrafPtr        currentPort;
  301.         
  302.     if (((theEvent->what >= mouseDown) && (theEvent->what <= autoKey))
  303.             || !PtInRect(theEvent->where, &locals->mouseSlop)) {
  304.         
  305.         /* Brighten the control */
  306.         
  307.         if (locals->stage != 0) {
  308.             RgnHandle    firstMask = NewRgn();
  309.             RgnHandle    secondMask = NewRgn();
  310.             
  311.             GetDItem(theDialog, ok, &itemType, &handle, &box);
  312.             GetPort(¤tPort);
  313.             SetPort(theDialog);
  314.             iconBox.left = ((box.left + box.right) >> 1) - fingerFromLeft;
  315.             iconBox.right = iconBox.left + fingerSize;
  316.             iconBox.top = ((box.top + box.bottom) >> 1) - fingerFromTop;
  317.             iconBox.bottom = iconBox.top + fingerSize;
  318.             (void)IconSuiteToRgn(firstMask, &iconBox, atNone, globals->iconSuites[locals->stage - 1]);
  319.  
  320.             if (locals->stage > lastStage) {
  321.                 RectRgn(secondMask, &box);
  322.                 UnionRgn(firstMask, secondMask, firstMask);
  323.                 (*(ControlHandle)handle)->contrlHilite = 0;
  324.             }
  325.             InvalRgn(firstMask);
  326.             
  327.             /*    If there is a filter proc then send it an update event to force any
  328.                 additional drawing. */
  329.             ClipRect(&theDialog->portRect);
  330.             EraseRgn(firstMask);
  331.             if (locals->filterProc) {
  332.                 EventRecord theEvent = { updateEvt, (long)theDialog, TickCount(), { 0, 0 }, 0 };
  333.             
  334.                 (void)locals->filterProc(theDialog, &theEvent, itemHit);
  335.             }
  336.             
  337.             if (!EmptyRgn(((WindowPeek)theDialog)->updateRgn)) {
  338.                 BeginUpdate(theDialog);
  339.                 DrawDialog(theDialog);
  340.                 EndUpdate(theDialog);
  341.             }            
  342.             
  343.             DisposeRgn(firstMask);
  344.             DisposeRgn(secondMask);
  345.             SetPort(currentPort);
  346.             locals->stage = 0;
  347.         }
  348.     
  349.         /* Reset the timer */
  350.         
  351.         locals->ticks = TickCount();
  352.         
  353.         /* Reset the mouseSlop */
  354.         
  355.         SetRect(&locals->mouseSlop, theEvent->where.h, theEvent->where.v,
  356.             theEvent->where.h, theEvent->where.v);
  357.         InsetRect(&locals->mouseSlop, -slopAmount, -slopAmount);
  358.         
  359.     } else if (locals->ticks + startTime + (locals->stage) * delayTime < TickCount()) {
  360.         if (locals->stage == 0) ObscureCursor();
  361.         if (locals->stage > lastStage) {
  362.             *itemHit = ok;
  363.             locals->timedOut = true;
  364.             return true;
  365.         } else {
  366.             RgnHandle    firstMask = NewRgn();
  367.             RgnHandle    secondMask = NewRgn();
  368.             
  369.             GetDItem(theDialog, ok, &itemType, &handle, &box);
  370.             GetPort(¤tPort);
  371.         
  372.             SetPort(theDialog);
  373.             iconBox.left = ((box.left + box.right) >> 1) - fingerFromLeft;
  374.             iconBox.right = iconBox.left + fingerSize;
  375.             iconBox.top = ((box.top + box.bottom) >> 1) - fingerFromTop;
  376.             iconBox.bottom = iconBox.top + fingerSize;
  377.             if (locals->stage != 0) {
  378.                 
  379.                 (void)IconSuiteToRgn(firstMask, &iconBox, atNone, globals->iconSuites[locals->stage - 1]);
  380.                 if (locals->stage == lastStage) {
  381.                     RectRgn(secondMask, &box);
  382.                     UnionRgn(firstMask, secondMask, firstMask);
  383.                     (*(ControlHandle)handle)->contrlHilite = inButton;
  384.                 }
  385.                 (void)IconSuiteToRgn(secondMask, &iconBox, atNone, globals->iconSuites[locals->stage]);
  386.                 DiffRgn(firstMask, secondMask, secondMask);
  387.                 InvalRgn(secondMask);
  388.                 /*    If there is a filter proc then send it an update event to force any
  389.                     additional drawing. */
  390.                 ClipRect(&theDialog->portRect);
  391.                 EraseRgn(secondMask);
  392.                 if (locals->filterProc) {
  393.                     EventRecord theEvent = { updateEvt, (long)theDialog, TickCount(), { 0, 0 }, 0 };
  394.                 
  395.                     (void)locals->filterProc(theDialog, &theEvent, itemHit);
  396.                 }
  397.                 if (!EmptyRgn(((WindowPeek)theDialog)->updateRgn)) {
  398.                     BeginUpdate(theDialog);
  399.                     DrawDialog(theDialog);
  400.                     EndUpdate(theDialog);
  401.                 }            
  402.             }
  403.             ClipRect(&theDialog->portRect);
  404.             
  405.             if (locals->isBWPort) {
  406.                 BlockMove(theDialog, &locals->bwPort, sizeof(GrafPort)); /* Blast back */
  407.                 BlockMove(&locals->colorPort, theDialog, sizeof(GrafPort)); /* Blast in a color port */
  408.             }
  409.             
  410.             PlotIconSuite(&iconBox, atNone, ttNone, globals->iconSuites[locals->stage]);
  411.             
  412.             if (locals->isBWPort) {
  413.                 BlockMove(&locals->bwPort, theDialog, sizeof(GrafPort)); /* Blast back */
  414.             }
  415.  
  416.             DisposeRgn(firstMask);
  417.             DisposeRgn(secondMask);
  418.             SetPort(currentPort);
  419.             ++locals->stage;
  420.         }
  421.     }
  422.     
  423.     if (locals->filterProc) {
  424.         return locals->filterProc(theDialog, theEvent, itemHit);
  425.     } else return false;
  426. }
  427.  
  428.  
  429.